package com.yu.handler;

import com.yu.apiutils.ApiResult;
import com.yu.apiutils.ApiResultUtils;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang3.StringUtils;

/**
 * @author maxinuyu
 * @date 2025/6/4
 * 重写了该接口的supports和beforeBodyWrite方法。
 *
 * supports方法决定了beforeBodyWrite方法是否执行，只有supports方法返回true时，beforeBodyWrite方法才会执行。
 * 在beforeBodyWrite方法中，将接口的返回值使用ApiResultUtils.success方法做封装，如果返回值已经是ApiResult类型，则直接返回无需重复封装。
 */
@ControllerAdvice
public class GlobalApiResultHandler implements ResponseBodyAdvice<Object> {
    @Override
    // 判断是否需要处理
    public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
        // 获取当前请求
        ServletRequestAttributes sra = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        // 获取当前请求的URI
        HttpServletRequest request = sra.getRequest();
        String uri = request.getRequestURI();
        return matchUrl(uri);
    }

     /**
     * 匹配URL
     *
     * @param uri
     * @return
     */
    private boolean matchUrl(String uri) {
        // 如果为空，则不进行拦截
        if (StringUtils.isBlank(uri)) {
            return false;
        }
        // 匹配/v1
        return uri.contains("/v1");
    }

    // 处理返回结果
    @Override
    public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
        // 如果返回结果已经是ApiResult，则直接返回
        if (body instanceof ApiResult) {
            return (ApiResult) body;
        }
        // 返回成功
        return ApiResultUtils.success(body);
    }
}